package com.chenyue.cm.moudules.system.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.chenyue.cm.base.aop.Log;
import com.chenyue.cm.base.bean.Pageable;
import com.chenyue.cm.bean.Success;
import com.chenyue.cm.common.constant.C;
import com.chenyue.cm.common.utils.RequestUtil;
import com.chenyue.cm.common.utils.StringUtils;
import com.chenyue.cm.moudules.system.bean.MenuTreeBean;
import com.chenyue.cm.moudules.system.service.SysMenusService;
import com.chenyue.cm.moudules.system.service.SysRoleMenusService;
import com.chenyue.cm.moudules.system.service.SysUserRolesService;
import com.chenyue.cm.moudules.system.utils.CmTreeUtils;
import com.chenyue.cm.moudules.system.utils.ShiroUtils;
import com.chenyue.cm.system.domain.*;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSort;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * 【系统管理模块】----------菜单模块
 *
 * @author chenyue1993
 */
@Controller
@RequestMapping("/sysMenus")
@Api(value = "系统管理-菜单", tags = "系统管理-菜单")
@ApiSort(1)
public class SysMenusController {

    private final SysMenusService sysMenusService;

    @Resource
    private SysRoleMenusService sysRoleMenusService;

    private final SysUserRolesService userRoleService;

    private String themePrefix = C.THEME_Prefix;
    private String page_url_list = themePrefix + "system/sysmenus/sysMenusList";
    private String page_url_form = themePrefix + "system/sysmenus/sysMenusForm";
    private String page_menu_chooseIcon = themePrefix + "system/sysmenus/chooseIcon";
    private String page_menu_selectTree = themePrefix + "system/sysmenus/tree";

    public SysMenusController(SysMenusService sysMenusService, SysUserRolesService userRoleService) {
        this.sysMenusService = sysMenusService;
        this.userRoleService = userRoleService;
    }


    /**
     * 【CM页面跳转】跳转至菜单列表页面
     *
     * @param request
     * @param response
     * @param model
     * @return
     */
    @RequestMapping("/toList")
    public String toList(HttpServletRequest request, HttpServletResponse response, Model model) {

        return page_url_list;
    }

    /**
     * 【CM页面跳转】跳转至菜单编辑页面
     *
     * @param model
     * @param request
     * @param response
     * @return
     */
    @RequestMapping("/toForm")
    public String toForm(Model model, HttpServletRequest request, HttpServletResponse response) {
        String id = request.getParameter("id");
        String pid = request.getParameter("pid");
        SysMenus vo = (id != null && id != "") ? sysMenusService.selectByPrimaryKey(id) : new SysMenus();
        //子级菜单赋值
        if (pid != null && pid != "") {
            vo.setPid(pid);
        }
        model.addAttribute("vo", vo);
        return page_url_form;
    }

    /**
     * 【CM页面跳转】----(V2.0)跳转至菜单选择树
     *
     * @param model
     * @return
     */
    @RequestMapping("/selectMenuTree")
    public String selectMenuTree(HttpServletRequest request, HttpServletResponse response, Model model) {
        String menuId = request.getParameter("menuId");
        if (menuId != null && StringUtils.isNotEmpty(menuId)) {
            model.addAttribute("menu", sysMenusService.selectByPrimaryKey(menuId));
        } else {
            model.addAttribute("menu", new SysMenus());
        }
        return page_menu_selectTree;
    }


    /**
     * 【CM页面跳转】----选择菜单图标
     *
     * @param model
     * @return
     */
    @RequestMapping("/chooseIcon")
    public String chooseIcon(Model model) {
        return page_menu_chooseIcon;
    }


    /**
     * 【CM-API】获取菜单列表数据 （树形结构---平行格式 (由前端自主解析树形 )
     *
     * @param request
     * @param response
     * @return
     */
    @SuppressWarnings("unchecked")
    @RequestMapping("/getList")
    @ResponseBody
    @ApiOperation(value = "【S1001】获取整个菜单信息(非树形结构)", notes = "获取整个菜单树信息")
    @ApiOperationSupport(order = 1)
    @Log(value = "查询菜单列表信息", type = "1")
    public Success getList(HttpServletRequest request, HttpServletResponse response) {
        Pageable pageInfo = RequestUtil.getPageable(request);
        pageInfo.setPageSize(200);
        List<SysMenus> menuList;
        List<Map<String, Object>> resultList = new ArrayList<>();


        QueryWrapper<SysMenus> eWrapper = new QueryWrapper<>();
        eWrapper.orderBy(true, true,"pid, orderno");

        menuList = sysMenusService.list(eWrapper);
        for (SysMenus sysMenus : menuList) {
            Map<String, Object> map;
            map = JSON.parseObject(JSON.toJSONString(sysMenus), HashMap.class);
            if (map.get("pid") == null || "".equals(map.get("pid").toString())) {
                map.put("pid", 0);
            }
            resultList.add(map);
        }

        return Success.success(resultList);
    }


    /**
     * 【API】----  获取整个资源菜单树 （树形结构---树形格式 (children为子级数据 )
     *
     * @return Success
     */
    @PostMapping("/getMenuTree")
    @ResponseBody
    @ApiOperation(value = "【S1002】获取整个菜单信息（树形结构）", notes = "获取整个菜单树信息")
    @ApiOperationSupport(order = 2)
    @Log(value = "查询菜单列表信息", type = "1")
    public Success getMenuTree() {
        SysMenusExample e2 = new SysMenusExample();
        e2.setOrderByClause("order_no asc");
        List<SysMenus> allMenu = sysMenusService.selectByExample(e2);


        //获取树形结构的所有菜单信息
        List<Map<String, Object>> menuTreeList = CmTreeUtils.getTreeList(allMenu);

        return Success.success(menuTreeList);
    }


    /**
     * 【API】----  根据用户信息获取对应的菜单结构树
     *
     * @return Success
     */
    @PostMapping(value = "/getMenuListByUser")
    @ResponseBody
    @ApiOperation(value = "【S1003】根据登录用户获取菜单树", notes = "根据登录用户获取菜单树")
    @ApiOperationSupport(order = 3)
    @Log(value = "查询菜单列表信息（用户登录）", type = "1")
    public Success getMenuListByUser() {

        List<MenuTreeBean> rootMenu = new ArrayList<>();

        // 获取用户角色信息
        String roleId = "0";
        SysUsersRoleExample aExample = new SysUsersRoleExample();
        aExample.createCriteria().andUserIdEqualTo(ShiroUtils.getUserId());
        List<SysUsersRole> rolelist = userRoleService.selectByExample(aExample);
        if (rolelist.size() > 0) {
            roleId = rolelist.get(0).getRoleId();
        }

        //获取该角色对应的资源菜单树
        SysRoleMenusExample e1 = new SysRoleMenusExample();
        e1.createCriteria().andRoleIdEqualTo(roleId);
        List<SysRoleMenus> rolemenuList = sysRoleMenusService.selectByExample(e1);

        // 获取该用户角色对应的菜单权限
        List<String> checkedlist = new ArrayList<>();
        for (SysRoleMenus rm : rolemenuList) {
            String ridString = rm.getMenuId();
            checkedlist.add(ridString);
        }

        //获取所有资源菜单树
        SysMenusExample e2 = new SysMenusExample();
        e2.createCriteria().andTypeNotEqualTo(2);
        e2.setOrderByClause("order_no asc");
        List<SysMenus> allMenu = sysMenusService.selectByExample(e2);


        //获取树形结构的所有菜单信息
//		TreeConfigBean treeConfigBean  =  new TreeConfigBean();
//		List<Map<String, Object>> menuTreeList  =  CmTreeUtils.getCheckedTreeList(allMenu, treeConfigBean, checkedlist);
//		System.err.println(JSON.toJSONString(menuTreeList));


        for (SysMenus systemMenu : allMenu) {
            MenuTreeBean a = new MenuTreeBean();
            a.setId(systemMenu.getId());
            a.setName(systemMenu.getName());
            a.setLabel(systemMenu.getName());
            a.setCode(systemMenu.getCode());
            a.setPageurl(systemMenu.getPageurl());
            a.setOrderno(systemMenu.getOrderNo());
            a.setIcon(systemMenu.getIcon());
            a.setShowFlag(systemMenu.getShowFlag());
            a.setRemark(systemMenu.getRemark());
            List<MenuTreeBean> childList = getChild(systemMenu.getId(), allMenu, checkedlist);
            if ((checkedlist.contains(systemMenu.getId())) && (systemMenu.getPid() == null || "".equals(systemMenu.getPid()))) {
                a.setChildren(childList);
                rootMenu.add(a);
            } else if (childList.size() > 0 && (systemMenu.getPid() == null || "".equals(systemMenu.getPid()))) {
                a.setChildren(childList);
                rootMenu.add(a);
            }
        }

        return Success.success(rootMenu);
    }


    /**
     * 获取子节点
     *
     * @param id      父节点id
     * @param allMenu 所有菜单列表
     * @return 每个根节点下，所有子菜单列表
     */
    private List<MenuTreeBean> getChild(String id, List<SysMenus> allMenu, List<String> checkedlist) {
        // 子菜单
        List<MenuTreeBean> childList = new ArrayList<>();

        // 遍历所有节点，将所有菜单的父id与传过来的根节点的id比较
        for (SysMenus nav : allMenu) {
            if (checkedlist.contains(nav.getId()) || checkedlist.size() < 1) {
                // 相等说明：为该根节点的子节点。
                if (nav.getPid() != null && (nav.getPid().equals(id))) {
                    MenuTreeBean a = new MenuTreeBean();
                    a.setId(nav.getId());
                    a.setPid(nav.getPid());
                    a.setName(nav.getName());
                    a.setLabel(nav.getName());
                    a.setCode(nav.getCode());
                    a.setPageurl(nav.getPageurl());
                    a.setOrderno(nav.getOrderNo());
                    a.setIcon(nav.getIcon());
                    a.setShowFlag(nav.getShowFlag());
                    a.setRemark(nav.getRemark());
                    childList.add(a);
                }
            }
        }
        // 递归
        for (MenuTreeBean nav : childList) {
            nav.setChildren(getChild(nav.getId(), allMenu, checkedlist));
        }
        // 如果节点下没有子节点，返回一个空List（递归退出）
        if (childList.size() == 0) {
            return new ArrayList<MenuTreeBean>();
        }
        return childList;
    }


    /**
     * 保存菜单信息
     *
     * @param request
     * @return Success
     */
    @PostMapping("/save")
    @ResponseBody
    @ApiOperation(value = "【S1004】保存菜单基本信息", notes = "保存菜单基本信息")
    @ApiOperationSupport(order = 3)
    @Log(value = "保存菜单信息", type = "1")
    public Success save(SysMenus vo, HttpServletRequest request) {
        String id = request.getParameter("id");
        if (id != null && id != "") {
            sysMenusService.updateByPrimaryKey(vo);
        } else {
            vo.setId(UUID.randomUUID().toString().replace("-", ""));
            sysMenusService.save(vo);
        }
        return Success.success();
    }


    /**
     * 删除菜单信息
     *
     * @param id id
     * @return Success
     */
    @PostMapping("/delete/{id}")
    @ResponseBody
    @ApiOperation(value = "【S1005】删除单个菜单信息", notes = "删除单个菜单信息")
    @ApiOperationSupport(order = 7)
    @ApiImplicitParams({
            @ApiImplicitParam(value = "菜单主键id", name = "id", dataType = "String", required = true, paramType = "path")
    })
    @Log(value = "删除菜单信息", type = "1")
    public Success deleteByPrimaryKey(@PathVariable String id) {
        //菜单绑定角色---不可删除
        //删除 操作
        sysMenusService.deleteByPrimaryKey(id);
        return Success.success();
    }


    /**
     * 【API】----  删除多个数据
     *
     * @return Success
     */
    @RequestMapping("/delete")
    @ResponseBody
    public Success delete(String ids) {
        String[] idStrings = ids.split(",");
        for (String idString : idStrings) {
            sysMenusService.deleteByPrimaryKey(idString);
        }
        return Success.success();
    }

}
